package mx.ipn.persistencia.mysql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.sql.Date;

import mx.ipn.persistencia.FabricaDeDAOs;
import mx.ipn.persistencia.dao.PersonaDAO;
import mx.ipn.persistencia.dao.PuestoDAO;
import mx.ipn.persistencia.dao.EmpleadoDAO;
import mx.ipn.to.PersonaTO;
import mx.ipn.to.EmpleadoTO;
import mx.ipn.to.FechaHoraTO;

public class EmpleadoDAOMySQL implements EmpleadoDAO {
	static{FabricaDeDAOsMySQL.iniciaLog(EmpleadoDAOMySQL.class);}

	private static final String INSERT = "INSERT INTO empleado (nss,fecha_ingreso,dias_vacaciones,id_puesto,id_persona,activo) VALUES(?,?,?,?,?,?)";
	private static final String ACTIVADESACTIVAEMPLEADO = "UPDATE empleado SET activo=? WHERE id_empleado=?";
	private static final String UPDATE = "UPDATE empleado SET nss=?,fecha_ingreso=?,dias_vacaciones=?,id_puesto=?,id_persona=?,activo=? WHERE id_empleado=?";

	private static final String FINDBYID = "SELECT * FROM empleado WHERE id_empleado=?";
	private static final String FINDBYNSS = "SELECT * FROM empleado WHERE nss=? AND activo = true";
	private static final String FINDBYNSSACTIVOEINACTIVO = "SELECT * FROM empleado WHERE nss=?";
	private static final String FINDBYCURPACTIVO = "SELECT id_empleado,nss,fecha_ingreso,dias_vacaciones,id_puesto,empleado.id_persona,activo FROM empleado,persona WHERE empleado.id_persona=persona.id_persona AND UPPER(REPLACE(persona.curp,' ',''))=UPPER(REPLACE(?,' ','')) AND empleado.activo = true";

	private static final String SELECT = "SELECT * FROM empleado";
	private static final String SELECTACTIVO = "SELECT * FROM empleado WHERE activo=true";
	private static final String SELECTBYPATERNOACTIVO = "SELECT id_empleado,nss,fecha_ingreso,dias_vacaciones,id_puesto,empleado.id_persona,activo FROM empleado,persona WHERE empleado.id_persona=persona.id_persona AND UPPER(REPLACE(persona.apellido_paterno,' ',''))=UPPER(REPLACE(?,' ','')) AND empleado.activo = true";
	private static final String SELECTBYNOMBREPATERNOACTIVO = "SELECT id_empleado,nss,fecha_ingreso,dias_vacaciones,id_puesto,empleado.id_persona,activo FROM empleado,persona WHERE empleado.id_persona=persona.id_persona AND UPPER(REPLACE(persona.nombre,' ','')) LIKE UPPER(REPLACE(?,' ','')) AND UPPER(REPLACE(persona.apellido_paterno,' ',''))=UPPER(REPLACE(?,' ','')) AND empleado.activo = true";
	private static final String SELECTACTIVOBYPUESTO = "SELECT * FROM empleado WHERE id_puesto=? AND activo=true";
	private static final String SELECTBYPUESTO = "SELECT * FROM empleado WHERE id_puesto=?";

	@Override
	public short activaDesactivaEmpleado(int idEmpleado, boolean activo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion
					.prepareStatement(ACTIVADESACTIVAEMPLEADO);

			ps.setBoolean(1, activo);
			ps.setInt(2, idEmpleado);

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

	
	@Override
	public EmpleadoTO findEmpleadoByCurp(String curp) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYCURPACTIVO);
			ps.setString(1, curp);
			ResultSet rs = ps.executeQuery();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			PuestoDAO puestoDAO = fabricaMySQL.getPuestoDAO();
			PersonaDAO personaDAO = fabricaMySQL.getPersonaDAO();

			if (rs.next()) {
				int idEmpleado = rs.getInt("id_empleado");
				String nss = rs.getString("nss");
				java.sql.Date fechaIngreso = rs.getDate("fecha_ingreso");
				short diasVacaciones = rs.getShort("dias_vacaciones");
				boolean activo = rs.getBoolean("activo");

				EmpleadoTO empleadoTO = new EmpleadoTO(idEmpleado, nss,
						fechaIngreso, diasVacaciones, puestoDAO
								.findPuestoById(rs.getShort("id_puesto")),
						personaDAO.findPersonaById(rs.getInt("id_persona")),
						activo);

				ps.close();
				conexion.close();
				return empleadoTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


	@Override
	public EmpleadoTO findEmpleadoById(int idEmpleado) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYID);
			ps.setInt(1, idEmpleado);
			ResultSet rs = ps.executeQuery();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			PuestoDAO puestoDAO = fabricaMySQL.getPuestoDAO();
			PersonaDAO personaDAO = fabricaMySQL.getPersonaDAO();

			if (rs.next()) {
				idEmpleado = rs.getInt("id_empleado");
				String nss = rs.getString("nss");
				java.sql.Date fechaIngreso = rs.getDate("fecha_ingreso");
				short diasVacaciones = rs.getShort("dias_vacaciones");
				boolean activo = rs.getBoolean("activo");

				EmpleadoTO empleadoTO = new EmpleadoTO(idEmpleado, nss,
						fechaIngreso, diasVacaciones, puestoDAO
								.findPuestoById(rs.getShort("id_puesto")),
						personaDAO.findPersonaById(rs.getInt("id_persona")),
						activo);

				ps.close();
				conexion.close();
				return empleadoTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public EmpleadoTO findEmpleadoByNss(String nss) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYNSS);
			ps.setString(1, nss);
			ResultSet rs = ps.executeQuery();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			PuestoDAO puestoDAO = fabricaMySQL.getPuestoDAO();
			PersonaDAO personaDAO = fabricaMySQL.getPersonaDAO();

			if (rs.next()) {
				int idEmpleado = rs.getInt("id_empleado");

				java.sql.Date fechaIngreso = rs.getDate("fecha_ingreso");
				short diasVacaciones = rs.getShort("dias_vacaciones");
				boolean activo = rs.getBoolean("activo");

				EmpleadoTO empleadoTO = new EmpleadoTO(idEmpleado, nss,
						fechaIngreso, diasVacaciones, puestoDAO
								.findPuestoById(rs.getShort("id_puesto")),
						personaDAO.findPersonaById(rs.getInt("id_persona")),
						activo);

				ps.close();
				conexion.close();
				return empleadoTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	

	@Override
	public EmpleadoTO findEmpleadoByNssActivoEInactivo(String nss) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYNSSACTIVOEINACTIVO);
			ps.setString(1, nss);
			ResultSet rs = ps.executeQuery();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			PuestoDAO puestoDAO = fabricaMySQL.getPuestoDAO();
			PersonaDAO personaDAO = fabricaMySQL.getPersonaDAO();

			if (rs.next()) {
				int idEmpleado = rs.getInt("id_empleado");

				java.sql.Date fechaIngreso = rs.getDate("fecha_ingreso");
				short diasVacaciones = rs.getShort("dias_vacaciones");
				boolean activo = rs.getBoolean("activo");

				EmpleadoTO empleadoTO = new EmpleadoTO(idEmpleado, nss,
						fechaIngreso, diasVacaciones, puestoDAO
								.findPuestoById(rs.getShort("id_puesto")),
						personaDAO.findPersonaById(rs.getInt("id_persona")),
						activo);

				ps.close();
				conexion.close();
				return empleadoTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


	@Override
	public boolean insertEmpleado(EmpleadoTO empleadoTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(INSERT);

			ps.setString(1, empleadoTO.getNss());
			ps.setDate(2, FechaHoraTO.getFecha(empleadoTO.getFechaIngreso()));
			ps.setShort(3, empleadoTO.getDiasVacaciones());
			ps.setShort(4, empleadoTO.getPuestoTO().getIdPuesto());
			ps.setInt(5, empleadoTO.getPersonaTO().getIdPersona());
			ps.setBoolean(6, empleadoTO.getActivo());
			ps.executeUpdate();

			ps.close();
			conexion.close();

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public ArrayList<EmpleadoTO> selectEmpleado() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<EmpleadoTO> empleadoTO = null;
			EmpleadoTO empleadoTO2 = null;

			PreparedStatement ps = conexion.prepareStatement(SELECT);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (empleadoTO == null) {
					empleadoTO = new ArrayList<EmpleadoTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				empleadoTO2 = new EmpleadoTO(rs.getInt("id_empleado"), rs
						.getString("nss"), rs.getDate("fecha_ingreso"), rs
						.getShort("dias_vacaciones"), puestoDAO
						.findPuestoById(rs.getShort("id_puesto")), personaDAO
						.findPersonaById(rs.getInt("id_persona")), rs
						.getBoolean("activo"));

				empleadoTO.add(empleadoTO2);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	
	@Override
	public ArrayList<EmpleadoTO> selectEmpleadoByPaternoActivo(String paterno) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<EmpleadoTO> empleadoTO = null;
			EmpleadoTO empleadoTO2 = null;
			
			
			
			PreparedStatement ps = conexion.prepareStatement(SELECTBYPATERNOACTIVO);

			ps.setString(1, paterno);
			
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (empleadoTO == null) {
					empleadoTO = new ArrayList<EmpleadoTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				empleadoTO2 = new EmpleadoTO(rs.getInt("id_empleado"), rs
						.getString("nss"), rs.getDate("fecha_ingreso"), rs
						.getShort("dias_vacaciones"), puestoDAO
						.findPuestoById(rs.getShort("id_puesto")), personaDAO
						.findPersonaById(rs.getInt("id_persona")), rs
						.getBoolean("activo"));

				empleadoTO.add(empleadoTO2);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}


	@Override
	public ArrayList<EmpleadoTO> selectEmpleadoByNombrePaternoActivo(
			String nombre, String paterno) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<EmpleadoTO> empleadoTO = null;
			EmpleadoTO empleadoTO2 = null;
			
			
			
			PreparedStatement ps = conexion.prepareStatement(SELECTBYNOMBREPATERNOACTIVO);
			nombre = "%" + nombre;
			nombre = nombre + "%";
			ps.setString(1, nombre);
			ps.setString(2, paterno);
			
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (empleadoTO == null) {
					empleadoTO = new ArrayList<EmpleadoTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				empleadoTO2 = new EmpleadoTO(rs.getInt("id_empleado"), rs
						.getString("nss"), rs.getDate("fecha_ingreso"), rs
						.getShort("dias_vacaciones"), puestoDAO
						.findPuestoById(rs.getShort("id_puesto")), personaDAO
						.findPersonaById(rs.getInt("id_persona")), rs
						.getBoolean("activo"));

				empleadoTO.add(empleadoTO2);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}

	@Override
	public ArrayList<EmpleadoTO> selectEmpleadoActivo() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<EmpleadoTO> empleadoTO = null;
			EmpleadoTO empleadoTO2 = null;

			PreparedStatement ps = conexion.prepareStatement(SELECTACTIVO);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (empleadoTO == null) {
					empleadoTO = new ArrayList<EmpleadoTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				empleadoTO2 = new EmpleadoTO(rs.getInt("id_empleado"), rs
						.getString("nss"), rs.getDate("fecha_ingreso"), rs
						.getShort("dias_vacaciones"), puestoDAO
						.findPuestoById(rs.getShort("id_puesto")), personaDAO
						.findPersonaById(rs.getInt("id_persona")), rs
						.getBoolean("activo"));

				empleadoTO.add(empleadoTO2);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public EmpleadoTO selectEmpleadoActivoByPuesto(short idPuesto) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<Integer> listIdEmpleado = null;
			ArrayList<String> listNss = null;
			ArrayList<java.sql.Date> listFechaIngreso = null;
			ArrayList<Short> listDiasVacaciones = null;
			ArrayList<PersonaTO> listPersonaTO = null;
			ArrayList<Boolean> listActivo = null;

			EmpleadoTO empleadoTO = null;

			PreparedStatement ps = conexion
					.prepareStatement(SELECTACTIVOBYPUESTO);
			ps.setShort(1, idPuesto);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdEmpleado == null) {

					listIdEmpleado = new ArrayList<Integer>();
					listNss = new ArrayList<String>();
					listFechaIngreso = new ArrayList<java.sql.Date>();
					listDiasVacaciones = new ArrayList<Short>();
					listPersonaTO = new ArrayList<PersonaTO>();
					listActivo = new ArrayList<Boolean>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				listIdEmpleado.add(rs.getInt("id_empleado"));
				listNss.add(rs.getString("nss"));
				listFechaIngreso.add(rs.getDate("fecha_ingreso"));
				listDiasVacaciones.add(rs.getShort("dias_vacaciones"));
				listPersonaTO.add(personaDAO.findPersonaById(rs
						.getInt("id_persona")));
				listActivo.add(rs.getBoolean("activo"));
			}
			if (listIdEmpleado != null) {

				PersonaTO[] arrPersonaTO = (PersonaTO[]) listPersonaTO
						.toArray(new PersonaTO[listPersonaTO.size()]);
				Integer[] arrIdEmpleado = (Integer[]) listIdEmpleado
						.toArray(new Integer[listIdEmpleado.size()]);
				String[] arrNss = (String[]) listNss.toArray(new String[listNss
						.size()]);
				Date[] arrFechaIngreso = (Date[]) listFechaIngreso
						.toArray(new Date[listFechaIngreso.size()]);
				Short[] arrDiasVacaciones = (Short[]) listDiasVacaciones
						.toArray(new Short[listDiasVacaciones.size()]);
				Boolean[] arrActivo = (Boolean[]) listActivo
						.toArray(new Boolean[listActivo.size()]);

				empleadoTO = new EmpleadoTO(arrIdEmpleado, arrNss,
						arrFechaIngreso, arrDiasVacaciones, puestoDAO
								.findPuestoById(idPuesto), arrPersonaTO,
						arrActivo);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public EmpleadoTO selectEmpleadoByPuesto(short idPuesto) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			PuestoDAO puestoDAO = null;
			PersonaDAO personaDAO = null;

			ArrayList<Integer> listIdEmpleado = null;
			ArrayList<String> listNss = null;
			ArrayList<java.sql.Date> listFechaIngreso = null;
			ArrayList<Short> listDiasVacaciones = null;
			ArrayList<PersonaTO> listPersonaTO = null;
			ArrayList<Boolean> listActivo = null;

			EmpleadoTO empleadoTO = null;

			PreparedStatement ps = conexion.prepareStatement(SELECTBYPUESTO);
			ps.setShort(1, idPuesto);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdEmpleado == null) {

					listIdEmpleado = new ArrayList<Integer>();
					listNss = new ArrayList<String>();
					listFechaIngreso = new ArrayList<java.sql.Date>();
					listDiasVacaciones = new ArrayList<Short>();
					listPersonaTO = new ArrayList<PersonaTO>();
					listActivo = new ArrayList<Boolean>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					puestoDAO = fabricaMySQL.getPuestoDAO();
					personaDAO = fabricaMySQL.getPersonaDAO();
				}

				listIdEmpleado.add(rs.getInt("id_empleado"));
				listNss.add(rs.getString("nss"));
				listFechaIngreso.add(rs.getDate("fecha_ingreso"));
				listDiasVacaciones.add(rs.getShort("dias_vacaciones"));
				listPersonaTO.add(personaDAO.findPersonaById(rs
						.getInt("id_persona")));
				listActivo.add(rs.getBoolean("activo"));
			}
			if (listIdEmpleado != null) {

				PersonaTO[] arrPersonaTO = (PersonaTO[]) listPersonaTO
						.toArray(new PersonaTO[listPersonaTO.size()]);
				Integer[] arrIdEmpleado = (Integer[]) listIdEmpleado
						.toArray(new Integer[listIdEmpleado.size()]);
				String[] arrNss = (String[]) listNss.toArray(new String[listNss
						.size()]);
				Date[] arrFechaIngreso = (Date[]) listFechaIngreso
						.toArray(new Date[listFechaIngreso.size()]);
				Short[] arrDiasVacaciones = (Short[]) listDiasVacaciones
						.toArray(new Short[listDiasVacaciones.size()]);
				Boolean[] arrActivo = (Boolean[]) listActivo
						.toArray(new Boolean[listActivo.size()]);

				empleadoTO = new EmpleadoTO(arrIdEmpleado, arrNss,
						arrFechaIngreso, arrDiasVacaciones, puestoDAO
								.findPuestoById(idPuesto), arrPersonaTO,
						arrActivo);
			}
			ps.close();
			conexion.close();
			return empleadoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public short updateEmpleado(EmpleadoTO empleadoTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(UPDATE);

			ps.setString(1, empleadoTO.getNss());
			ps.setDate(2, FechaHoraTO.getFecha(empleadoTO.getFechaIngreso()));
			ps.setShort(3, empleadoTO.getDiasVacaciones());
			ps.setShort(4, empleadoTO.getPuestoTO().getIdPuesto());
			ps.setInt(5, empleadoTO.getPersonaTO().getIdPersona());
			ps.setBoolean(6, empleadoTO.getActivo());
			ps.setInt(7, empleadoTO.getIdEmpleado());
			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			} else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}

	}

}
